package net.net23.sysdent.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import net.net23.sysdent.JNumberTextField;
import net.net23.sysdent.PropertiesDialog;
import net.net23.sysdent.PropertiesFields;
import net.net23.sysdent.sql.DBEngine;
import net.net23.sysdent.sql.exception.DataBaseConnectionException;
import net.sysdent.jdbcexplorer.api.AutocompleteProvider;
import net.sysdent.jdbcexplorer.api.OracleAutocompleteProvider;
import net.sysdent.jdbcexplorer.api.SQL92KeyWords;

public class ConnectionDialog extends PropertiesDialog {

	private static final long serialVersionUID = -6672689876555996773L;

	private JTextField driver;
	private JTextField url;
	private JTextField user;
	private JPasswordField password;
	private JCheckBox autoCommit;
	private JTextField catalog;
	private JCheckBox readOnly;
	private JNumberTextField timeOut;

	private JButton connect;
	private JButton cancel;

	private AutocompleteComponent autocompleteComponent;

	public ConnectionDialog(AutocompleteComponent autocompleteComponent) {
		super("Parametros de conexión", 370, 250);
		this.autocompleteComponent = autocompleteComponent;
		initFields();
		initButtons();
		PropertiesFields fields = new PropertiesFields();
		fields.addField("Driver:*", driver);
		fields.addField("Url:*", url);
		fields.addField("User:", user);
		fields.addField("Password:", password);
		fields.addField("Autocommit:", autoCommit);
		fields.addField("Catalog:", catalog);
		fields.addField("Read only:", readOnly);
		fields.addField("Login timeout:", timeOut);
		build(fields, connect, cancel);
		setVisible(true);
	}

	private void initFields() {
		Properties connectionProperties = loadConnection();
		driver = new JTextField(getProperty(connectionProperties, "driver",
				"oracle.jdbc.driver.OracleDriver"));
		url = new JTextField(getProperty(connectionProperties, "url",
				"jdbc:oracle:thin:@host:port:sid"));
		user = new JTextField(getProperty(connectionProperties, "user", ""));
		password = new JPasswordField(getProperty(connectionProperties,
				"password", ""));
		autoCommit = new JCheckBox();
		readOnly = new JCheckBox();
		readOnly.setSelected(true);
		catalog = new JTextField();
		timeOut = new JNumberTextField();
	}

	private String getProperty(Properties properties, String key,
			String defValue) {
		String value = properties.getProperty(key);
		if (value == null) {
			value = defValue;
		}
		return value;
	}

	private Properties loadConnection() {
		Properties properties = new Properties();
		try {
			properties.load(new FileInputStream(new File(
					"connection.properties")));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return properties;
	}

	private void initButtons() {
		connect = new JButton("Conectar");
		connect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				connect();
			}
		});
		cancel = new JButton("Cerrar");
		cancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				closeDialog();
			}
		});
	}

	protected void connect() {
		if (validateFields()) {
			Properties properties = new Properties();
			properties.setProperty("driver", driver.getText());
			properties.setProperty("url", url.getText());
			properties.setProperty("user", user.getText());
			properties.setProperty("password",
					String.valueOf(password.getPassword()));
			properties.setProperty("catalog", catalog.getText());
			properties.setProperty("readOnly", readOnly.isSelected() ? "1"
					: "0");
			properties.setProperty("autoCommit", autoCommit.isSelected() ? "1"
					: "0");
			try {
				DBEngine.createConnection(properties);
				setupAutocompletePRoviders();
				closeDialog();
			} catch (DataBaseConnectionException e) {
				e.printStackTrace();
				setError(e.getMessage());
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				setError(e.getMessage());
			} catch (SQLException e) {
				e.printStackTrace();
				setError(e.getMessage());
			}
		}
	}

	public void setupAutocompletePRoviders() throws SQLException,
			DataBaseConnectionException {
		AutocompleteProvider[] providers = new AutocompleteProvider[] {
				new SQL92KeyWords(), new OracleAutocompleteProvider() };
		for (AutocompleteProvider autocompleteProvider : providers) {
			String sql = autocompleteProvider.getSQl();
			ResultSet rs = null;
			if (sql != null) {
				rs = DBEngine.executeNativeQuery(sql).executeQuery();
			}
			Set<String> autocompleteCollection = autocompleteProvider
					.getAutocompleteCollection(rs);
			autocompleteComponent.addProvider(autocompleteCollection);
		}

		autocompleteComponent.setupAutocomplete();
	}

	private boolean validateFields() {
		String _driver = driver.getText();
		String _url = url.getText();
		String _timeOut = timeOut.getText();
		if (_driver.trim().length() == 0) {
			setError("El Driver es obligatorio");
			driver.requestFocus();
			return false;
		}
		if (_url.trim().length() == 0) {
			setError("El Driver es obligatorio");
			url.requestFocus();
			return false;
		}
		if (_timeOut.trim().length() > 0) {
			if (!timeOut.isValidValue()) {
				timeOut.requestFocus();
				return false;
			}
		}
		return true;
	}
}
